//使用严格模式的js。保证js的严谨，作为一个好习惯。
'use strict';

//使用require引入所有需要的模块，这是node.js语法，不了解的话记住就行了。
    //gulp
var gulp        = require('gulp'),
    //多浏览器多设备同步&自动刷新
    browserSync = require('browser-sync').create(),
    SSI         = require('browsersync-ssi'),
    //整合文件
    concat      = require('gulp-concat'),
    gulpif 		= require('gulp-if'),
    //压缩js
    uglify      = require('gulp-uglify'),
    minifyCss 	= require('gulp-clean-css'),
    minifyHtml 	= require('gulp-htmlmin'),
    //错误处理插件plumber
    plumber     = require('gulp-plumber'),
    // 用来编译sass
    sass 		= require('gulp-sass'),
    //clean 用来删除文件
    clean       = require('gulp-clean'),
    //压缩文件
    zip         = require('gulp-zip'),
    //图片处理
    cache 		= require('gulp-cache'),
    imagemin 	= require('gulp-imagemin'),
    //自动添加后缀
    autoprefixer = require('gulp-autoprefixer'),
    //对文件名加MD5后缀
    rev = require('gulp-rev'),         
    //- 路径替换
	revCollector = require('gulp-rev-collector'),   
	//替换src js外部引入带inline的
	inlinesource = require('gulp-inline-source'),
    //控制task中的串行和并行。这个很重要，它能够严格规定task的执行顺序，否则gulp默认并行，有些时候会产生问题。如先清空再重建文件，可能重建过程中又清空了。
    runSequence = require('gulp-run-sequence');
    
//上边引入模块之后，下面开始编写任务:

var cssSrc = 'src/css/*.scss',
	cssDest = 'dist/css',
	jsSrc = 'src/js/*.js',
	jsDest = 'dist/js',
	fontSrc = 'src/fonts/*',
	fontDest = 'dist/font',
	imgSrc = 'src/images/*',
	imgDest = 'dist/images',
	condition = true;


//创建一个名为serve的任务，该任务的内容就是匿名函数中的内容。
gulp.task('serve', function() {
    //使用browserSync创建服务器，自动打开浏览器并打开./dist文件夹中的文件（默认为index.html）
    browserSync.init({
        server: {
            baseDir:["./dist"],
            middleware:SSI({
                baseDir:'./dist',
                ext:'.shtml',
                version:'2.10.0'
            })
        }
    });
    //监听各个目录的文件，如果有变动则执行相应的任务操作文件
    gulp.watch("src/css/**/*.scss", ['reload']);
    gulp.watch("src/js/**/*.js", ['reload']);
    gulp.watch("src/**/*.html", ['miniHtml']);
    //如果有任何文件变动，自动刷新浏览器
    gulp.watch("dist/**/*").on("change",browserSync.reload);
});

//下面来分别看看处理各个部分的任务：

//为css中引入的图片/字体等添加hash编码
//gulp.task('assetRev', function(){
//return gulp.src(cssSrc)  //该任务针对的文件
// .pipe(assetRev()) //该任务调用的模块
// .pipe(gulp.dest('src/css')); //编译后的路径
//});


//处理图片
gulp.task('images', function() {
  return gulp.src(imgSrc)
  	.pipe(plumber())
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest(imgDest))
});

//js任务，将js压缩后放入dist。该任务要在clean-scripts任务完成后再执行
gulp.task('miniJs', function(){
        //首先取得app/javascript下的所有后缀为.js的文件（**/的意思是包含所有子文件夹）
    return gulp.src(jsSrc)
        //错误管理模块
        .pipe(plumber())
        //js压缩
        .pipe(gulpif(
			condition, uglify()
		))
        //版本号处理
        .pipe(rev())
        //输出到dist/javascript
        .pipe(gulp.dest(jsDest))
    	.pipe(rev.manifest())
    	.pipe(gulp.dest('src/rev/js'))
});

//compass任务，将scss编译为css
gulp.task('miniCss', function() {
	gulp.src('src/css/**/*.css')
        .pipe(gulp.dest('dist/css'))
	return gulp.src(cssSrc) 
		.pipe(plumber()) 
		.pipe(sass.sync().on('error', sass.logError)) 
		.pipe(sass({outputStyle:"compact"}))
		.pipe(gulpif(
			condition, minifyCss({
				compatibility: 'ie7',
				keepSpecialComments: '*'
				//保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀，如果不加这个参数，有可能将会删除你的部分前缀
			})
		))
		.pipe(rev())
		.pipe(autoprefixer({
			browsers: ['last 5 versions', 'Android >= 4.0'],
			cascade: false,
			remove: false	   
		}))
		.pipe(gulp.dest(cssDest))
		.pipe(rev.manifest())
		.pipe(gulp.dest('src/rev/css'))
});


//压缩Html/更新引入文件版本
gulp.task('miniHtml', function () {
	return gulp.src(['src/rev/**/*.json', 'src/*.html'])
		.pipe(revCollector())
		.pipe(gulpif(
			condition, minifyHtml({
				removeComments: true,  //清除HTML注释
		        collapseWhitespace: true,  //压缩HTML
		        collapseBooleanAttributes: true,  //省略布尔属性的值 <input checked="true"/> ==> <input checked />
		        removeEmptyAttributes: true,  //删除所有空格作属性值 <input id="" /> ==> <input />
		        removeScriptTypeAttributes: true,  //删除<script>的type="text/javascript"
		        removeStyleLinkTypeAttributes: true,  //删除<style>和<link>的type="text/css"
		        minifyJS: true,  //压缩页面JS
		        minifyCSS: true  //压缩页面CSS
			})
		))
		.pipe(gulp.dest('dist'));
});

//压缩Html/更新引入文件版本
gulp.task('inline', function () {
	var options = {
        compress: false
    };
	return gulp.src('dist/*.html')
		.pipe(gulpif(
			condition, inlinesource()
		))
		.pipe(gulpif(
			!condition, inlinesource(options)
		))
		.pipe(gulp.dest('dist'));
});

		

//clean任务：清空dist文件夹，下边重建dist的时候使用
gulp.task('clean', function () {
  return gulp.src(['dist/*','rev/*'], {read: false})
    .pipe(clean());
});

//publish任务，需要的时候手动执行，将dist中的文件打包压缩放到release中。
gulp.task('publish', function(){
        //取得dist文件夹中的所有文件
    return gulp.src('dist/**/*')
        //错误处理模块
        .pipe(plumber())
        //压缩成名为publish.zip的文件
        .pipe(zip('publish.zip'))
        //放入release文件夹
        .pipe(gulp.dest('release'))
});

//开发构建
gulp.task('reload', function (done) {
	runSequence(
		['miniCss', 'miniJs'],
		['miniHtml'],
		['inline'],
	done);
});

//开发构建
gulp.task('dev', function (done) {
	condition = false;
	runSequence(
		['clean'],
		['images','miniCss', 'miniJs'],
		['miniHtml'],
		['inline'],
		['serve'],
	done);
});
//正式构建
gulp.task('build', function (done) {
	runSequence(
		['clean'],
		['images','miniCss', 'miniJs'],
		['miniHtml'],
		['inline'],
	done);
});
gulp.task('default', ['build']);